<template>
  <el-container style="height: 500px; border: 1px solid #eee">
    <el-aside width="280px" class="left-tree">
      <el-tree lazy node-key="id" ref="tree" :props="props" :load="loadNode" :highlight-current="true" :expand-on-click-node="false" @node-click="handleNodeClick" />
    </el-aside>
    <el-main style="padding:5px">
      <os-table autoHeight stripe :autoLoad="false" :selected = selected :otherSearch="otherSearch" action="system/userPageByOrgId" ref="osTable" v-loading="loading" pageNumField="pageNo" :columns="columns" :form="form" :btn="btn" size="small" border>
      </os-table>
    </el-main>
  </el-container>
</template>
<script>
// import { mapGetters } from 'vuex'
export default {
  name: 'UserPage',
  data () {
    return {
      props: {
        label: 'orgName',
        children: 'children',
        isLeaf: 'leaf'
      },
      form: {
        rule: [
          { type: 'Input', title: '账号', field: 'userName' },
          { type: 'Input', title: '用户名', field: 'realName' },
          { type: 'el-button', field: 'search', props: { type: 'primary' }, children: ['查询'], emit: ['click'] },
          { type: 'el-button', field: 'clear', props: { type: 'primary' }, children: ['清空'], emit: ['click'] }
        ]
      },
      btn: [
        { text: '新增', cb: () => this.onAdd() },
        { text: '新增已有用户', cb: () => this.onAddUser() },
        { text: '启用', cb: () => this.onFrozenBatch('1') },
        { text: '停用', cb: () => this.onFrozenBatch('0') },
        { text: '删除', cb: () => this.onDeleteBatch() }
      ],
      columns: [
        { type: 'selection', width: 40 },
        { label: '用户账号', prop: 'userName' },
        { label: '真实姓名', prop: 'realName' },
        {
          label: '性别',
          prop: 'gender',
          formatter: (row) => {
            return this.$c.dictCode.gender.filter(i => {
              return i.value === row.gender
            })[0].label
          },
          width: 50
        },
        { label: '手机号码', prop: 'phone', width: 110 },
        { label: '邮箱', prop: 'email' },
        {
          label: '状态',
          prop: 'validation',
          formatter: (row) => {
            return this.$c.dictCode.status.find(i => i.value === row.validation).label
          },
          width: 50
        },
        {
          label: '操作',
          prop: 'action',
          fixed: 'right',
          width: 120,
          headerAlign: 'center',
          align: 'center',
          renderCell: (data) => {
            const list = [
              { label: '编辑', cb: () => this.onEdit(data) },
              { label: '重置密码', cb: () => this.onResetPwd(data) },
              { label: '停用', show: data.row.validation === '1', cb: () => this.onFrozen(data, 0) },
              { label: '启用', show: data.row.validation === '0', cb: () => this.onFrozen(data, 1) },
              { label: '删除', cb: () => this.onDel(data) }
            ]
            return <os-table-dropdown list={list} />
          }
        }
      ],
      fApi: null,
      rule: [
        { type: 'hidden', title: 'id', field: 'id' },
        { type: 'hidden', title: 'orgId', field: 'orgId' },
        { type: 'Input', title: '部门', field: 'orgName' },
        { type: 'Input', title: '用户账号', field: 'userName', validate: [this.$v.required()] },
        { type: 'Input', title: '真实姓名', field: 'realName', validate: [this.$v.required()] },
        { type: 'Input', title: '密码', field: 'passWord', props: { type: 'password' } },
        { type: 'Input', title: '重复密码', field: 'passWord2', props: { type: 'password' } },
        { type: 'Input', title: '手机号码', field: 'phone', validate: [this.$v.required()] },
        { type: 'Input', title: '邮箱', field: 'email', validate: [this.$v.required()] },
        { type: 'Radio', title: '主管部门', field: 'isMajor' },
        { type: 'Radio', title: '性别', field: 'gender' },
        { type: 'Radio', title: '用户状态', field: 'validation' },
        { type: 'DatePicker', title: '生日', field: 'birthday', props: { valueFormat: 'yyyy-MM-dd' } },
        { type: 'DatePicker', title: '入职时间', field: 'entryDate', props: { valueFormat: 'yyyy-MM-dd' } }, // hh:mm:ss
        { type: 'DatePicker', title: '离职时间', field: 'leaveDate', props: { valueFormat: 'yyyy-MM-dd' } },
        {
          type: 'OsInputTable',
          title: '岗位',
          field: 'positionIds',
          props: {
            action: 'system/selectPositionPage',
            labelField: 'positionName',
            otherSearch: { org: '-1' },
            form: {
              rule: [
                { type: 'Input', title: '岗位编码', field: 'positionCode' },
                { type: 'Input', title: '岗位名称', field: 'positionName' },
                { type: 'el-button', field: 'search', props: { type: 'primary' }, children: ['查询'], emit: ['click'] },
                { type: 'el-button', field: 'clear', props: { type: 'primary' }, children: ['清空'], emit: ['click'] }
              ]
            },
            columns: [
              { type: 'selection', width: 40 },
              { label: '部门名称', prop: 'orgName' },
              { label: '岗位编码', prop: 'positionCode' },
              { label: '岗位名称', prop: 'positionName' }
            ],
            dialogProps: { width: '60%' }
          },
          on: {
            select: this.getSelectValue
          }
          // validate: [this.$v.required()]
        },
        { type: 'Select', title: '职务', field: 'titleIds', props: { filterable: true }, options: [] },
        {
          type: 'OsSelect',
          title: '角色',
          field: 'roles',
          value: [],
          props: { name: 'roles', multiple: true, filterable: true },
          // col: { span: 16 },
          options: [] // 这里必须要有，不然不会显示结果
          // validate: [this.$v.required('array')]
        }
      ],
      option: {
        ...this.$utils.formOptions(),
        mounted: $f => {
          this.$utils.setOptions($f, 'roles', 'roleName', 'id', 'system/roleAll')
          this.$utils.setOptions($f, 'titleIds', 'titleName', 'id', 'system/getAllTitle')
          this.$utils.updateFormOptions($f, 'gender', this.$c.dictCode.gender)
          this.$utils.updateFormOptions($f, 'isMajor', this.$c.dictCode.validation)
          this.$utils.updateFormOptions($f, 'validation', this.$c.dictCode.status)
        }
      },
      otherSearch: { orgId: '-1' },
      selected: [],
      nodeData: {}, // 点击后的父节点数据,主要用于增、修、删
      loading: false
    }
  },
  computed: {
  },
  watch: {
  },
  methods: {
    /** 获取数据 */
    async loadNode (node, resolve) {
      if (node.level === 0) {
        return this.loadTreeData(resolve, node)
      }
      this.loadTreeData(resolve, node)
      return resolve([]) // 加上这个，防止在该节点没有子节点时一直转圈的问题发生。
    },
    async loadTreeData (resolve, node) {
      let parentId = '-1'
      if (node?.data) {
        parentId = node.data.id
      }
      const { data } = await this.$store.dispatch('system/getOrgByParentId', { parentId: parentId })
      // 系统会在左边树数据加载完成后，再根据树节点的第一个节点组织ID加载右边列表数据
      if (data && parentId === '-1') {
        this.nodeData = data[0]
        this.loadTableData(this.nodeData)
      }
      resolve(data)
    },
    handleNodeClick (data, node) {
      this.nodeData = data
      this.selected = []
      this.loadTableData(data)
    },
    getSelectValue (data) {
      console.info('value: ' + data)
    },
    loadTableData (data) {
      if (data) {
        this.otherSearch = { orgId: data.id }
      } else {
        this.otherSearch = { orgId: '-1' }
      }
      this.$refs.osTable.getData()
    },
    onAddUser () {
      if (!this.nodeData) {
        this.$utils.message.warning('请选择组织机构！')
      }
    },
    onAdd () {
      if (!this.nodeData) {
        this.$utils.message.warning('请选择组织机构！')
        return
      }
      this.onHandle()
    },
    async onEdit ({ row }) {
      this.loading = true
      const { data } = await this.$store.dispatch('system/userGetById', { id: row.id, orgId: this.nodeData.id })
      // const { data } = await this.$store.dispatch('system/getRolesByUserId', row.id)
      // row.roles = data.map(r => r.id)
      row = Object.assign({}, data)
      if (data.positionIds) {
        row.positionIds = { ids: data.positionIds, names: data.positionNames }
      }
      this.loading = false
      this.onHandle(row)
    },
    onHandle (row = { roles: [] }) {
      const btn = [{ text: '保存', loading: true, cb: this.save }]
      this.$utils.dialog(`${row.id ? '编辑' : '添加'}用户`, <form-create vModel={this.fApi} rule={this.rule} option={this.option} />, { btn })
      this.$nextTick(() => {
        this.$f.resetFields(this.fApi, row)
        const node = this.nodeData
        this.fApi.setValue({ orgId: node.id, orgName: node.orgName })
        this.fApi.disabled(true, 'orgName')
        // 给岗位选择列表，添加组织ID参数
        this.fApi.model().positionIds.props.otherSearch = this.otherSearch
        if (row.id) {
          this.fApi.disabled(true, 'userName')
          this.fApi.hidden(true, ['passWord', 'passWord2'])
          this.fApi.updateValidate('passWord', [])
          this.fApi.updateValidate('passWord2', [])
        } else {
          this.fApi.setValue({ gender: '1', priorityDepartId: '0', validation: '1' })
          this.fApi.disabled(false, 'userName')
          this.fApi.hidden(false, ['passWord', 'passWord2'])
          this.fApi.updateValidate('passWord', [this.$v.required()])
          this.fApi.updateValidate('passWord2', [this.$v.required(), this.$v.validator(this.validatorPWD)])
        }
      })
    },
    validatorPWD (rule, value, callback) {
      const user = this.fApi.formData()
      if (user.passWord !== user.passWord2) {
        callback(new Error('2次输入密码不一致'))
      } else {
        callback()
      }
    },
    async onResetPwd ({ row }) {
      const re = await this.$utils.confirm('确认要重置密码吗？')
      if (!re) return
      const { data } = await this.$store.dispatch('system/resetPwd', { id: row.id })
      if (data) {
        this.$utils.alert('新密码为：123abcA!', '重置成功')
      }
    },
    async onDel ({ row }) {
      const re = await this.$utils.confirm('确认要删除吗？')
      if (!re) return
      const { error } = await this.$store.dispatch('system/userDelete', { id: row.id, orgId: this.nodeData.id })
      if (!error) {
        this.$utils.message.success('删除成功')
        this.$refs.osTable.getData()
      }
    },
    async onDeleteBatch () {
      const re = await this.$utils.confirm('确认要删除吗？')
      if (!re) return
      const ids = this.selected.map(e => e.id)
      const { error } = await this.$store.dispatch('system/deleteBatch', { ids: ids, orgId: this.nodeData.id })
      if (!error) {
        this.$utils.message.success('删除成功')
        this.$refs.osTable.getData()
      }
    },
    async onFrozen ({ row }, status) {
      const { error } = await this.$store.dispatch('system/userFrozen', { ids: row.id, status })
      if (!error) {
        this.$utils.message.success(`${status === 1 ? '启用' : '停用'}成功!`)
        this.$refs.osTable.getData()
      }
    },
    async onFrozenBatch (status) {
      const ids = this.selected.map(e => e.id)
      const { error } = await this.$store.dispatch('system/userFrozen', { ids: ids, status })
      if (!error) {
        this.$utils.message.success(`${status === 1 ? '启用' : '停用'}成功!`)
        this.$refs.osTable.getData()
      }
    },
    save (cb) {
      this.fApi.validate(async (valid) => {
        if (valid) {
          const formData = this.fApi.formData()
          // console.info('-----------formData: ' + JSON.stringify(formData))
          const { error } = await this.$store.dispatch('system/userSave', formData)
          cb()
          if (!error) {
            this.$utils.message.success('保存成功')
            this.$utils.hideDialog()
            this.$refs.osTable.getData()
          }
        } else {
          cb()
          console.log('表单校验失败')
        }
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.left-tree {
  background-color: #fff ;
  border : 1px solid #eee ;
  margin: 5px;
  }
</style>
